#ifndef __AUTO_STATUS_H
#define __AUTO_STATUS_H

#define PLUGIN_ID			"gtk-plugin_pack-autostatus"
#define PURPLE_WEBSITE      "http://bluehua.org"
#define PLUGIN_NAME			"Auto Change Status"
#define DISPLAY_VERSION     "0.1"
#define PLUGIN_STATIC_NAME  autostatus 
#define PLUGIN_SUMMARY		"auto change IM status according to the network or time"
#define PLUGIN_DESCRIPTION	"auto change IM status according to the network or time"
#define PLUGIN_AUTHOR		"Hua Lu <emptyhua@gmail.com>"

#define PURPLE_PLUGINS

#include <stdio.h>
#include <string.h>
#include <glib.h>
#include <gtk/gtk.h>

/* Purple headers */
#include <libpurple/version.h>
#include <libpurple/debug.h>
#include <pidgin/gtkplugin.h>

#include <libpurple/savedstatuses.h>
#include <libpurple/eventloop.h>
#include <libpurple/status.h>
#include <libpurple/util.h>

#include <libpurple/conversation.h>
#include <pidgin/gtkconv.h>
#include <pidgin/gtkprefs.h>
#include <pidgin/gtkutils.h>
#include <pidgin/gtksavedstatuses.h>

#include <dbus/dbus-glib.h>
#include <nm-connection.h>
#include <nm-setting-connection.h>
#include <NetworkManager.h>
#include <nm-utils.h>

#define TIMEOUT_CHECK_INTERVAL 5
#define	PREF_PREFIX	"/plugins/gtk/" PLUGIN_ID
#define PREF_CFG_SAVED_RULE PREF_PREFIX "/saved_rules"


#define DEBUG(format, ...) purple_debug(PURPLE_DEBUG_INFO, "autostatus", format"\n", ##__VA_ARGS__)

#define DBUS_TYPE_G_MAP_OF_VARIANT          (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
#define DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT   (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT))
#define DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH    (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH))

typedef struct _network_connection_st network_connection_t;
struct _network_connection_st
{
    char *id;
    char *uuid;
    char *type;
    network_connection_t *next;
};

enum {
	SS_MENU_ENTRY_TYPE_PRIMITIVE,
	SS_MENU_ENTRY_TYPE_SAVEDSTATUS
};

enum {
	/** _SSMenuEntryType */
	SS_MENU_TYPE_COLUMN,

	/**
	 * This is a GdkPixbuf (the other columns are strings).
	 * This column is visible.
	 */
	SS_MENU_ICON_COLUMN,

	/** The text displayed on the status box.  This column is visible. */
	SS_MENU_TEXT_COLUMN,

	/**
	 * This value depends on SS_MENU_TYPE_COLUMN.  For _SAVEDSTATUS types,
	 * this is the creation time.  For _PRIMITIVE types,
	 * this is the PurpleStatusPrimitive.
	 */
	SS_MENU_DATA_COLUMN,

	/**
	 * This is the emblem to use for this status
	 */
	SS_MENU_EMBLEM_COLUMN,

	/**
	 * And whether or not that emblem is visible
	 */
	SS_MENU_EMBLEM_VISIBLE_COLUMN,

	SS_MENU_NUM_COLUMNS
};

enum {
    NETWORK_CONNECT_ID = 0,
    NETWORK_CONNECT_UUID,
    NETWORK_CONNECT_TYPE,
    NETWORK_COLUMNS
};

enum {
    SAVED_CFG_RULE = 0,
    SAVED_CFG_DATA,
    SAVED_CFG_COLUMNS
};

enum {
   TIME_INTERVAL_NAME,
   TIME_INTERVAL_VALUE,
   TIME_INTERVAL_COLUMNS
};

#define TIME_INTERVAL_EVERYDAY 1
#define TIME_INTERVAL_WORKDAY 2
#define TIME_INTERVAL_WEEKEND 3

#define RULE_TYPE_NETWORK 1 
#define RULE_TYPE_TIME 2

typedef struct ConfigRuleSt
{
    char *name;
    int rule_type;
    char *netid;
    char *uuid;

    int status_type;
    int status_key;

    int time_seconds;
    int time_interval;
    struct ConfigRuleSt *next;
} ConfigRule;

typedef struct AutoStatusSt
{
    ConfigRule *rules;
    network_connection_t *active_connections;
    DBusGConnection *dbus;
    DBusGProxy *nm_proxy;
    PurplePlugin *info;
    int check_timer;
} AutoStatus;

typedef struct
{
	GtkWidget *frame;
    AutoStatus *plugin;

	GtkWidget *status_selector_for_net;
	GtkWidget *net_selector;
	GtkWidget *saved_network_rules_list;
    
    GtkWidget *time_selector;
    GtkWidget *time_interval_selector;
	GtkWidget *saved_time_rules_list;
	GtkWidget *status_selector_for_time;
} ConfigWindow;

ConfigRule *config_rules_new();
void config_rules_free(ConfigRule *rule);

PurpleSavedStatus *get_saved_status(int status_type, int status_key);

GtkWidget *saved_network_rules_list_new(ConfigWindow *dialog);
GtkWidget *saved_time_rules_list_new(ConfigWindow *dialog);

void load_rules(AutoStatus *plg);
void save_rules(AutoStatus *plg);

int delete_rule(AutoStatus *plg, ConfigRule *rule);
ConfigRule *add_network_rule(AutoStatus *plg, char *status_title, int status_type, int status_key, char *netid, char *uuid);
ConfigRule *add_time_rule(AutoStatus *plg, char *status_title, int status_type, int status_key, char *time_string, int time_interval);

void network_connections_free(network_connection_t *connection);
network_connection_t *get_active_network_connections(DBusGConnection *dbus);
GtkWidget *network_select_menu_new();
GtkWidget *time_select_menu_new();
GtkWidget *time_interval_select_menu_new();

int active_status_by_network(AutoStatus *plg, network_connection_t *connection);
void active_status_by_time(AutoStatus *plg);

int is_network_connection_active(AutoStatus *plg, network_connection_t *connection);
#endif
